﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Xml;
using System.Text;
using System.Reflection;

namespace SmartDatingService {
    /// <summary>
    /// Specialized compact PersonalData object serializer
    /// </summary>
    public class PDSerializer {
        private static string[] PROP_NAMES = { "usr_id",
                "first_name",
                "last_name",
                "gender",
                "date_of_birth",
                "u_height",
                "u_weight",
                "hair_color",
                "eye_color",
                "main_size",
                "chest",
                "waist",
                "hip",
                "orientation",
                "zodiac",
                "reason",
                "interests",
                "bio",
                "picture",
                "phone_number",
                "icq",
                "jabber"};

        public static object ReadObject(Stream inStream) {
            XmlTextReader reader = new XmlTextReader(inStream);

            PersonalData pd = new PersonalData();
            Type pdType = typeof(PersonalData);

            reader.Read();
            while (!reader.EOF) {
                if (reader.NodeType == XmlNodeType.Element) {
                    if (reader.Name == "pd") {
                        reader.Read();
                        continue;
                    }
                    string propName = reader.Name;
                    object value = reader.ReadElementContentAsObject();

                    PropertyInfo prop = pdType.GetProperty(propName);
                    Type propType = prop.PropertyType;
                    if (propType == typeof(Guid)) {
                        prop.SetValue(pd, new Guid(value.ToString()), null);
                    } else if (propType == typeof(Nullable<int>)) {
                        prop.SetValue(pd, new Nullable<int>((Convert.ToInt32(value))), null);
                    } else if (propType == typeof(Byte[])) {
                        prop.SetValue(pd, Convert.FromBase64String((string)value), null);
                    } else {
                        prop.SetValue(pd, Convert.ChangeType(value, propType), null);
                    }
                } else {
                    reader.Read();
                }
            }

            reader.Close();
            return pd;
        }

        public static void WriteObject(Stream outStream, object pd) {
            XmlTextWriter writer = new XmlTextWriter(outStream, Encoding.UTF8);
            writer.WriteStartElement("pd");

            Type pdType = typeof(PersonalData);

            foreach (string propName in PROP_NAMES) {
                PropertyInfo prop = pdType.GetProperty(propName);
                object value = prop.GetValue(pd, null);
                if (value != null) {
                    writer.WriteStartElement(propName);
                    if (prop.PropertyType == typeof(Byte[])) {
                        writer.WriteString(Convert.ToBase64String((Byte[])value));
                    } else {
                        writer.WriteString(value.ToString());
                    }
                    writer.WriteEndElement();
                }
            }

            writer.WriteEndElement();
            writer.Close();
        }
    }
}